<?php
/*
 * Copyright (c) 2021.  Liuhongbin All rights reserved.
 * @domain http://dkyx.cc
 * @author liuhongbin <514660094@qq.com>
 */

namespace app\controller\adminapi\system;

use think\facade\Env;
use think\facade\Cache;
use hiduoke\services\CloudServer;
use hiduoke\controller\BaseController;
use FormBuilder\Driver\CustomComponent;
use hiduoke\services\FormBuilder as Form;
use app\common\model\system\Config as ConfigModel;

/**
 * Notes: 系统配置
 * Create by :  刘泓宾<514660094@qq.com>
 * Copyright :  copyright (c) 多客怪兽, www.dkyx.cc
 * Created on:  2025/8/6 03:48
 */
class Config extends BaseController
{
    /**
     * @var ConfigModel
     */
    protected $model;

    protected $notLogin = ['getLoginConfig', 'getAllConfig'];

    protected function initialize()
    {
        parent::initialize();
        $this->model = new ConfigModel();
    }

    public function index()
    {
        $data = array(
            ['label' => "站点设置", 'key' => 'site'],
            ['label' => '登录页', 'key' => 'login'],
            ['label' => '关于我们', 'key' => 'about'],
            ['label' => "短信配置", 'key' => 'sms'],
            ['label' => "远程附件", 'key' => "remote"],
            ['label' => "缓存配置", 'key' => "cache"],
            ['label' => "云设置", 'key' => 'cloud'],
            ['label' => '域名绑定', 'key' => 'domain']
        );
        return $this->success('ok', $data);
    }

    public function domain()
    {
        $domain = \think\facade\Config::get('domain', []);
        $res = [];
        foreach ($domain as $key => $value) {
            $value['key'] = $key;
            $res[] = $value;
        }
        $rule = array();
        //创建表单
        $form = Form::createForm("/adminapi/system/config/setDomain")->setMethod("post");
        //新增表单
        $rule[] = Form::dkGroup('domain', "域名配置", $res)->rule([
            Form::input('key', '域名')->effect(['help' => '可以填写完整域名或者是域名前缀'])->required(),
            Form::input('addon_name', '模块标识')->effect(['help' => '请填写模块名称，如store、admin、workOpenWechat'])->required(),
            Form::switches('force_domain', '域名强制')->effect(['help' => '设置后，将仅仅使用当前域名访问'])
                ->activeValue(true)
                ->inactiveValue(false),
            Form::input('plaid', 'plaid')->effect(['help' => '请填写plaid']),
            Form::input('appid', 'appid')->effect(['help' => '请填写appid']),
        ]);
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    public function setDomain()
    {
        $formData = input("formData", []);
        $domain = [];
        foreach ($formData['domain'] ?? [] as $key => $value) {
            $domain[$value['key']] = [
                'addon_name'   => $value['addon_name'],
                'force_domain' => $value['force_domain'] ?? false,
                'plaid'        => $value['plaid'],
                'appid'        => $value['appid'],
            ];
        }
        // 将配置写入文件
        $configPath = config_path() . 'domain.php';
        $configContent = "<?php\nreturn " . var_export($domain, true) . ";\n";
        try {
            file_put_contents($configPath, $configContent);
            return $this->success("修改成功", $domain);
        } catch (\Exception $e) {
            return $this->error("保存配置文件失败: " . $e->getMessage());
        }
    }

    /**
     * 缓存配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function cache()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("cache");
        $form = Form::createForm("/adminapi/system/config/setCache")->setMethod("post");
        //新增表单
        $rule[] = Form::radio('driver', '缓存驱动', $res['driver'] ?? 'file')->options([
            ['label' => '本地文件', 'value' => 'file'],
            ['label' => 'Redis', 'value' => 'redis'],
            ['label' => 'Memcache', 'value' => 'memcache'],
            ['label' => 'Memcached', 'value' => 'memcached'],
        ])->effect(['help' => '设置缓存驱动，如果设置后，网站无法打开，请修改根目录env文件driver属性改为file，设置Redis、Memcache、Memcached缓存驱动，需要先再php中安装对应的扩展，并在宝塔安装对应的软件，如果使用的非本地服务器，配置IP等其他信息也在config/cache.php中']);
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }


    public function setCache()
    {
        $formData = input("formData", []);
        if ($formData['driver'] != 'file') {
            try {
                Cache::store($formData['driver']);
            } catch (\Exception $e) {
                if ($e->getMessage() == "Connection refused") {
                    return $this->error('连接被拒绝');
                } else if ($e->getMessage() == "not support: memcache") {
                    return $this->error("不支持：memcache,请先安装扩展！");
                } else if ($e->getMessage() == 'not support: memcached') {
                    return $this->error("不支持：memcached,请先安装扩展！");
                }
                return $this->error($e->getMessage());
            }
        }
        Env::offsetSet('CACHE.DRIVER', $formData['driver']);
        $envPath = root_path() . DIRECTORY_SEPARATOR . '.env';
        $envinidata = Env::get();
        $inicontent = $this->arr_trinsform_ini($envinidata);
        $fp = fopen($envPath, "w") or die("Couldn't open $envPath");
        fputs($fp, $inicontent);
        fclose($fp);
        $this->model->setValueByKey($formData, 'cache');
        return $this->success("修改成功");
    }


    private function arr_trinsform_ini(array $a, array $parent = array())
    {
        $out = '';
        $keysindent = [];
        foreach ($a as $k => $v) {
            if (is_array($v)) {
                $sec = array_merge((array)$parent, (array)$k);
                $out .= '[' . join('.', $sec) . ']' . PHP_EOL;
                $out .= $this->arr_trinsform_ini($v, $sec);
            } else {
                $key = explode('_', $k);
                if (count($key) > 1 && !in_array($key[0], $keysindent)) {
                    $keysindent[] = $key[0];
                    $out .= PHP_EOL;
                    $out .= "[$key[0]]" . PHP_EOL;
                    unset($key[0]);
                    $out .= implode('_', $key) . " = $v" . PHP_EOL;
                } elseif (count($key) > 1 && in_array($key[0], $keysindent)) {
                    unset($key[0]);
                    $out .= implode('_', $key) . " = $v" . PHP_EOL;
                } else {
                    $out .= "$k = $v" . PHP_EOL;
                }
            }
        }
        return $out;
    }

    /**
     * 云端配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function cloud()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("cloud");
        $form = Form::createForm("/adminapi/system/config/save?key=cloud")->setMethod("post");
        //新增表单
        $rule[] = Form::dkInput("site_id", "站点ID", $res['site_id'] ?? '');
        $rule[] = Form::dkInput("token", "站点Token", $res['token'] ?? '');
        $rule[] = Form::dkInput("version", "站点版本", $res['version'] ?? config('hiduoke.version'));
        $rule[] = Form::dkInput("domain", "绑定域名", $res['domain'] ?? request()->server("SERVER_NAME"));
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 站点配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function site()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("site");
        $form = Form::createForm("/adminapi/system/config/save?key=site")->setMethod("post");
        //新增表单
        $rule[] = Form::dkInput("name", "站点名称", $res['name'] ?? '', '配置后将显示到后台左上角，配合Logo使用，logo推荐尺寸1:1');
        $rule[] = Form::dkImage("logo", "站点logo", $res['logo'] ?? '');
        $rule[] = Form::dkInput("title", "站点标题", $res['title'] ?? '', '系统默认站点标题');
        $rule[] = Form::dkInput("icp", "备案信息", $res['icp'] ?? '', '客户端页面的底部备案信息');
        $rule[] = Form::dkInput("copyright", "版权信息", $res['copyright'] ?? 'Copyright © 2021 成都多客怪兽科技有限公司 All Rights Reserved', '填写自定义版权信息');
        $rule[] = Form::select('default_index', "域名跳转", $res['default_index'] ?? 1)
            ->options([
                ['label' => '后台登录页', 'value' => 1],
                ['label' => '自定义跳转地址', 'value' => 2],
                ['label' => '自定义iframe嵌套', 'value' => 3]

            ])->appendControl(2,
                [
                    Form::dkInput('default_index_url', '自定义跳转地址', $res['default_index_url'] ?? '', '设置自定义跳转地址，比如用户访问域名根目录则会跳转到这个地址')
                ]
            )->appendControl(3,
                [
                    Form::dkInput('default_index_url', '自定iframe地址', $res['default_index_url'] ?? '', '设置自定义iframe地址，设置后将会嵌套这个页面')
                ]
            );
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 客户端配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function customer()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("customer");
        $form = Form::createForm("/adminapi/system/config/save?key=customer")->setMethod("post");
        //新增表单
        $rule[] = Form::dkInput("name", "站点名称", $res['name'] ?? '', '配置后将显示到后台左上角，配合Logo使用，logo推荐尺寸1:1');
        $rule[] = Form::dkImage("logo", "站点logo", $res['logo'] ?? '');
        $rule[] = Form::dkInput("title", "站点标题", $res['title'] ?? '', '系统默认站点标题');
        $rule[] = Form::dkInput("icp", "备案信息", $res['icp'] ?? '', '客户端页面的底部备案信息,为空则不显示');
        $rule[] = Form::dkInput("copyright", "版权信息", $res['copyright'] ?? 'Copyright © 2021 成都多客怪兽科技有限公司 All Rights Reserved', '填写自定义版权信息');
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 登陆页面配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function login()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("login");
        $form = Form::createForm("/adminapi/system/config/save?key=login")->setMethod("post");
        //新增表单
        $rule[] = Form::dkInput("title", "页面名称", $res['title'] ?? '', '登录页显示的标题');
        $rule[] = Form::dkImage("bg_image", "背景图", $res['bg_image'] ?? '')->effect(['help' => '登录页背景图,推荐尺寸1920*1080']);
        $rule[] = Form::color("bg_color", "背景色", $res['bg_color'] ?? '')->effect(['help' => '设置背景色']);
        $rule[] = Form::dkInputNumber('borderRadius', "弧度", $res['borderRadius'] ?? 20, '登录框弧度,默认20');
        $rule[] = Form::dkInput("slogan", "页面标语", $res['slogan'] ?? '', '设置页面标语，将显示到登录页标题下');
        $rule[] = Form::select('custom_left', '左侧自定义', $res['custom_left'] ?? '0')
            ->options([
                ['label' => '简易配置', 'value' => '0'],
                ['label' => '完全自定义', 'value' => '1'],
                ['label' => '不需要左侧内容', 'value' => '-1'],
            ])
            ->appendControl('0', [
                Form::dkImage("l_image", "左侧图", $res['l_image'] ?? ''),
            ])->appendControl('1', [
                Form::dkTinyEditor('left_content', '左侧内容', $res['left_content'] ?? '')
            ])->effect(['help' => '设置后将使用富文本去设置左侧内容，内容完全自定义']);
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 关于我们
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function about()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("about");
        $form = Form::createForm("/adminapi/system/config/save?key=about")->setMethod("post");
        //新增表单
        $rule[] = Form::dkInput("corporate_name", "公司名称", $res['corporate_name'] ?? '');
        $rule[] = Form::dkInput("true_name", "联系人", $res['true_name'] ?? '');
        $rule[] = Form::dkInput("phone", "联系电话", $res['phone'] ?? '');
        $rule[] = Form::dkInput("qq", "联系QQ", $res['qq'] ?? '');
        $rule[] = Form::dkInput("email", "联系邮箱", $res['email'] ?? '');
        $rule[] = Form::dkInput("address", "联系地址", $res['address'] ?? '');

        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 短信配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function sms()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("sms");
        $form = Form::createForm("/adminapi/system/config/save?key=sms")->setMethod("post");
        //新增表单
        $rule[] = Form::radio("type", "短信平台", $res['type'] ?? 'aliyun')
            ->button(true)
            ->size('small')
            ->options([
                    ['label' => '阿里短信', 'value' => 'aliyun'],
                    ['label' => '腾讯短信', 'value' => 'tenxun'],
                ]
            )->appendControl('aliyun', [
                Form::dkInput('aliyun_id', '应用key', $res['aliyun_id'] ?? '')->required(),
                Form::dkInput('aliyun_secret', '秘钥secret', $res['aliyun_secret'] ?? '')->required(),
                Form::dkInput('aliyun_sign', '签名', $res['aliyun_sign'] ?? '')->required(),
            ])->appendControl('tenxun', [
                Form::dkInput('tenxun_app_id', 'sdkAppId', $res['tenxun_app_id'] ?? '')->required(),
                Form::dkInput('tenxun_id', 'SecretId', $res['tenxun_id'] ?? '')->required(),
                Form::dkInput('tenxun_key', 'SecretKey', $res['tenxun_key'] ?? '')->required(),
                Form::dkInput('tenxun_sign', '签名', $res['tenxun_sign'] ?? '')->required(),
            ]);
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 企业微信服务商配置
     */
    public function workOpenWechat()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("workWechat");
        $form = Form::createForm("/adminapi/system/config/save?key=workWechat")->setMethod("post");
        $rule[] = Form::ElAlert()->title('企业微信服务商配置说明')
            ->description('注册地址：https://open.work.weixin.qq.com/ 注册后需要创建一个网页应用，权限能勾选尽量勾选即可。 ')
            ->type('warning')
            ->prop('style', 'margin: 20px 0;')
            ->showIcon(true);
        // 选择默认授权方式
        $rule[] = Form::radio("auth_type", "授权方式", $res['auth_type'] ?? 'manual')
            ->button(true)
            ->size('small')
            ->options([
                    ['label' => '企业内部开发（手动）', 'value' => 'manual'],
                    ['label' => '用户自由选择配置方式(推荐)', 'value' => 'auto'],
                    ['label' => '企业微服务商授权', 'value' => 'open'],
                ]
            )->effect(['help' => '默认为企业内部开发，也就是用户手动填写企业微信配置，如果配置了企业微服务商授权，那么用户就不需要填写企业微信配置，而是通过企业微服务商授权获取企业微信配置。']);

        $rule[] = Form::dkInput("corpid", "企业ID", $res['corpid'] ?? '', '企业微信服务商的企业ID')->required();
        $rule[] = Form::dkInput('secret', '企业Secret', $res['secret'] ?? '', '企业微信服务商的企业Secret')->required();
        $rule[] = Form::dkInput("suite_id", "应用SuiteID", $res['suite_id'] ?? '', '企业微信服务商后台网页应用->应用详情->SuiteID')->required();
        $rule[] = Form::dkInput("suite_secret", "应用Secret", $res['suite_secret'] ?? '', '企业微信服务商后台网页应用->应用详情->Secret')->required();
        $rule[] = Form::dkInput('token', 'Token', $res['token'] ?? '', '企业微信服务商后台网页应用->应用详情->Token')->required();
        $rule[] = Form::dkInput('aes_key', 'AESKey', $res['aes_key'] ?? '', '企业微信服务商后台网页应用->应用详情->EncodingAESKey')->required();
        //事件接收URL
//        $h2 = new CustomComponent("p");
//        $rule[] = $h2->appendChild("接收事件服务器")->prop("style", "margin-bottom:20px");
        $url = url('/' . config('hiduoke.work_wechat_app') . "/open/event", [], '', true)->build();
        $rule[] = Form::dkCopyInput("url", '接收事件URL', $url)
            ->appendRule("suffix", Form::getHelp("将当前地址填写至事件服务器URL，在企业微信服务商后台-应用管理-网页应用-回调配置-数据回调URL/指令回调URL"))
            ->disabled(true);
        $rule[] = (new CustomComponent("h4"))->appendChild("市场和审核配置")->prop("style", "margin-bottom:30px");
        $rule[] = Form::select('qr_auth_type', '授权类型', $res['qr_auth_type'] ?? '1')
            ->options([['label' => '正式授权', 'value' => '0'], ['label' => '测试授权', 'value' => '1']])
            ->effect(['help' => '设置当前服务商的扫码授权类型，如果已经审核通过的，请选择正式授权']);
        $rule[] = Form::switches('auto_platform', '自动创建平台', $res['auto_platform'] ?? '')
            ->effect(['help' => '开启后企业微信应用市场被添加后会自动创建企微微信平台，【审核】和【显示在应用市场】的时候请开启']);
        $rule[] = Form::input('auto_platform_uid', '自动创建归属', $res['auto_platform_uid'] ?? '1')
            ->effect(['help' => '自动创建平台后，平台归属的用户UID，管理员可后期移交给指定用户']);
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 抖音服务商配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function douyinMinAppOpen()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("douyinMinAppOpen");
        $form = Form::createForm("/adminapi/system/config/save?key=douyinMinAppOpen")->setMethod("post");
        $rule[] = Form::ElAlert()->title('抖音服务商配置说明')
            ->description('当前功能未对用户开放，仅内部使用')
            ->type('warning')
            ->prop('style', 'margin: 20px 0;')
            ->showIcon(true);
        // 选择默认授权方式
        $rule[] = Form::radio("auth_type", "授权方式", $res['auth_type'] ?? 'manual')
            ->button()
            ->size('small')
            ->options([
                    ['label' => '自建小程序（手动配置）', 'value' => 'manual'],
                    ['label' => '用户自由选择配置方式（未开放）', 'value' => 'auto'],
                    ['label' => '抖音服务商链接授权（未开放）', 'value' => 'open'],
                ]
            )->effect(['help' => '当前未对外部用户开放该功能']);
        //开发者ID
        $rule[] = (new CustomComponent("h3"))->appendChild("开发者ID")->prop("style", "margin-bottom:20px");
        $rule[] = Form::dkInput("component_appid", "appid", $res['component_appid'] ?? '', '第三方小程序应用 appid')->required();
        $rule[] = Form::dkInput('component_appsecret', 'APPSecret', $res['component_appsecret'] ?? '', '第三方小程序应用 APPSecret')->required();
        // 授权流程相关
        $rule[] = (new CustomComponent("h3"))->appendChild("授权流程相关")->prop("style", "margin-bottom:20px");
        $oauth_url = request()->domain() . '/dy/open/component_ticket';
        $rule[] = Form::dkCopyInput("oauth_url", '授权事件接收 URL', $oauth_url)
            ->appendRule("suffix", Form::getHelp("将当前地址填写至授权事件接收 URL，通过该 URL 接收小程序授权成功通知、授权解除通知，也用于接收 component_ticket"))
            ->disabled(true);
        // 授权后实现业务
        $rule[] = (new CustomComponent("h3"))->appendChild("授权后实现业务")->prop("style", "margin-bottom:20px");
        $message_event_url = request()->domain() . '/dy/open/message_event/appid/$APPID$/cgi';
        $rule[] = Form::dkCopyInput("message_event_url", '消息与事件接收 URL', $message_event_url)
            ->appendRule("suffix", Form::getHelp("将当前地址填写至授权事件接收 URL，通过该 URL 接收已授权小程序的消息和事件推送"))
            ->disabled(true);
        $rule[] = Form::dkInput("token", "TOKEN", $res['token'] ?? '', '消息验证 TOKEN 服务商在代授权小程序接收到消息后，用来验证信息，最长为 32 位，只能是大小写字母和数字')->required();
        $rule[] = Form::dkInput("key", "key", $res['key'] ?? '', '消息加密解密 KEY 服务商在代授权小程序接收到消息后，用来解密消息，必须是长度为 43 的字符串，只能是大小写字母和数字')->required();
        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 系统设置
     */
    public function system()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("system");
        $form = Form::createForm("/adminapi/system/config/save?key=system")->setMethod("post");
        //新增表单
        $rule[] = Form::ElTabs('file', 'card')
            ->appendChild(
                Form::ElTabPane('附件设置', 'file')
                    ->appendChildren([
                        Form::dkInput('file_size', '附件大小', $res['file_size'] ?? '2', '单位M')->required(),
                        // 附件类型
                        Form::dkInput('file_type', '附件类型', $res['file_type'] ?? 'jpg,png,gif,zip,rar,7z,doc,docx,xls,xlsx,ppt,pptx,pdf,txt', '多个类型用英文逗号隔开')->required(),
                        // 附件路径
                        Form::dkInput('file_path', '附件路径', $res['file_path'] ?? 'public/uploads', '附件存放路径')->required(),
                    ]))
            ->appendChild(
                Form::ElTabPane('性能优化', 'optimize')->appendChildren([

                ])
            )->appendChild(
                Form::ElTabPane('算法设置', 'algorithm')
                    ->appendChildren([

                    ]),
            );


        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }


//
//    /**
//     * 邮箱配置
//     * @return \think\response\Json
//     * @throws \FormBuilder\Exception\FormBuilderException
//     */
//    public function email()
//    {
//        $rule = array();
//        //创建表单
//        $res = $this->model->getValueByKey("email");
//        $form = Form::createForm("/adminapi/system/config/save?key=email")->setMethod("post");
//        //新增表单
//        $rule[] = Form::dkInput("host", "邮箱服务器", $res['host'] ?? '');
//        $rule[] = Form::dkInput("port", "端口", $res['port'] ?? '');
//        $rule[] = Form::dkInput("username", "邮箱账号", $res['username'] ?? '');
//        $rule[] = Form::dkInput("password", "邮箱密码", $res['password'] ?? '');
//        $rule[] = Form::dkInput("from_name", "发件人名称", $res['from_name'] ?? '');
//        $rule[] = Form::dkInput("from_email", "发件人邮箱", $res['from_email'] ?? '');
//        $rule[] = Form::dkInput("reply_name", "回复人名称", $res['reply_name'] ?? '');
//        $rule[] = Form::dkInput("reply_email", "回复人邮箱", $res['reply_email'] ?? '');
//        $rule[] = Form::dkInput("test_email", "测试邮箱", $res['test_email'] ?? '');
//        $rule[] = Form::radio("is_ssl", "是否开启SSL", $res['is_ssl'] ?? 0)
//            ->button(true)
//            ->size('small')
//            ->options([
//                    ['label' => '是', 'value' => 1],
//                    ['label' => '否', 'value' => 0],
//                ]
//            );
//        $form->setRule($rule);
//        return $this->success("", Form::getFormData($form));
//    }


    /**
     * 远程附件配置
     * @return \think\response\Json
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function remote()
    {
        $rule = array();
        //创建表单
        $res = $this->model->getValueByKey("remote");
        $form = Form::createForm("/adminapi/system/config/save?key=remote")->setMethod("post");
        $default_file_type = config('upload.fileExt', []);
//        $default_file_mime = config('upload.fileMime', []);
        $default_file_size = config('upload.filesize') / 1024;
        $max_upload_size = ini_get('upload_max_filesize');

        $rule[] = Form::ElCollapse(['file', 'algorithm'])
            ->appendChild(
                Form::ElCollapseItem('附件设置', 'file')
                    ->appendChildren([
                        Form::input('file_size', '附件大小', $res['file_size'] ?? $default_file_size)
                            ->effect(['help' => '设置单个附件上传的最大大小，单位Kb，并且请检查服务器允许上传的最大大小，当前为' . $max_upload_size])
                            ->appendChild(['type' => 'span', 'slot' => 'append', 'children' => ['KB',]])
                            ->required(),
                        // 附件后缀
                        Form::select('file_ext', '附件后缀', $res['file_ext'] ?? $default_file_type)
                            ->props(['allow-create' => true, 'multiple' => true, 'filterable' => true, 'style' => 'width:100%'])
                            ->options($this->getOption($default_file_type))
                            ->effect(['help' => '设置允许上传的附件后缀，可以直接在下拉菜单框中选择，也可以手动输入'])
                            ->required(),
                    ]))
            ->appendChild(
                Form::ElCollapseItem('引擎设置', 'algorithm')
                    ->appendChildren([
                        Form::radio("type", "存储引擎", $res['type'] ?? 'local')->button(true)->size('small')
                            ->options([
                                    ['label' => '本地（不推荐）', 'value' => 'local'],
                                    ['label' => '腾讯COS', 'value' => 'cos'],
                                    ['label' => '阿里OSS', 'value' => 'oss'],
                                    ['label' => '七牛Kodo', 'value' => 'kodo']
                                ]
                            )->appendControl('local', [
                                Form::ElAlert()->type('error')->style(['margin' => '10px 0'])->title('说明')
                                    ->description('本地存储无需配置，但是建议使用远程存储引擎，推荐使用对象存储')
                            ])->appendControl('cos', [
                                Form::ElAlert()
                                    ->type('info')->style(['margin' => '10px 0'])->title('说明')
                                    ->description("腾讯云后台-产品中心-对象存储-创建一个所在地跟服务器所在地一致，访问权限选择公有读私有写"),
                                Form::dkInput('cos_domain', '空间域名', $res['cos_domain'] ?? '')
                                    ->effect(['help' => '跨域配置：点击进入刚才创建的存储桶-基础设置-跨域访问CORS设置-添加规则，来源和Header都填写*，操作Methods都勾选'])->required(),
                                Form::dkInput('cos_secret_id', 'SecretId', $res['cos_secret_id'] ?? '')
                                    ->effect(['help' => '点击右上角头像个人中心-选择访问管理-访问秘钥-API秘钥管理，将此处的App ID，Secret ID，Secret Key复制到后台对应的位置即可'])
                                    ->required(),
                                Form::dkInput('cos_secret_key', 'SecretKey', $res['cos_secret_key'] ?? '')->effect(['help' => '如上所述'])->required(),
                                Form::dkInput('cos_storage_name', '存储桶名称', $res['cos_storage_name'] ?? '')->required(),
                                Form::dkInput('cos_storage_region', '所属地域', $res['cos_storage_region'] ?? '')
                                    ->effect(['help' => '地域请填写如：	成都（中国）（ap-chengdu） 则填写：ap-chengdu'])
                                    ->required(),
                            ])->appendControl('oss', [
                                Form::ElAlert()
                                    ->type('info')->style(['margin' => '10px 0'])->title('说明')
                                    ->description("打开阿里云后台，在搜索框搜索OSS，点击进入，创建Bucket，注意区域需要选择服务器所在的区域，读写权限选择公共读，其他权限使用默认设置即可，点击确定创建成功"),
                                Form::dkInput('oss_domain', '空间域名', $res['oss_domain'] ?? '')
                                    ->effect(['help' => "跨域配置：点击进入刚才创建的bucket，概览-基础设置-跨域访问-设置进入-创建规则，需要启用“返回Vary：Orgin”"])
                                    ->required(),
                                Form::dkInput('oss_access_key', 'AccessKey', $res['oss_access_key'] ?? '')
                                    ->effect(['help' => "阿里云后台点击右上角的头像个人中心，点击AccessKey管理-安全信息管理，将Access Key ID，Access Key Secret复制到此处"])
                                    ->required(),
                                Form::dkInput('oss_access_key_secret', 'Secret', $res['oss_access_key_secret'] ?? '')
                                    ->effect(['help' => '如上所述'])
                                    ->required(),
                                Form::dkInput('oss_bucket', '存储空间名称', $res['oss_bucket'] ?? '')->required(),
                                Form::dkInput('oss_endpoint', 'Endpoint地域', $res['oss_endpoint'] ?? '')->effect(['help'=>"配置Bucket地域Endpoint，例如：oss-cn-beijing.aliyuncs.com"])->required(),
                            ])->appendControl('kodo', [
                                Form::ElAlert()
                                    ->type('info')->style(['margin' => '10px 0'])->title('说明')
                                    ->description("打开七牛云后台，选择七牛产品-云产品-对象存储-空间管理-新建空间，存储区域选择当前服务器所在的区域，访问设置选择公有即可。"),
                                Form::dkInput('kodo_domain', '空间域名', $res['kodo_domain'] ?? '')
                                    ->effect(['help' => '跨域配置：七牛存储直接设置允许跨域即可，找到刚才创建的存储桶-设置-跨域设置-新增规则，来源和方法都使用*'])->required(),
                                Form::dkInput('kodo_access_key', 'AccessKey', $res['kodo_access_key'] ?? '')
                                    ->effect(['help' => "个人中心-选择秘钥管理进入个人中心秘钥管理，将此处的AccessKey，SecretKey复制到此处"])->required(),
                                Form::dkInput('kodo_secret_key', 'SecretKey', $res['kodo_secret_key'] ?? '')
                                    ->effect(['help' => '如上所述'])->required(),
                                Form::dkInput('kodo_storage_name', '空间名称', $res['kodo_storage_name'] ?? '')->required(),
                            ])->required()
                    ]),
            )
            ->style(['width' => '100%']);

        $form->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    /**
     * 存储配置
     * @return \think\response\Json
     */
    public function save()
    {
        $key = input("key", '');
        $clear = input("clear", '0');
        $formData = input("formData", []);
        if (!$clear) {
            $res = $this->model->getValueByKey($key);
            $formData = array_merge($res, $formData);
        }
        $this->model->setValueByKey($formData, $key);
        return $this->success("保存成功", $formData);
    }

    /**
     * 根据key获取配置
     * @param $key
     * @return \think\response\Json
     */
    public function getConfig($key)
    {
        $config = $this->model->getValueByKey($key);
        $config['get'] = true;
        return $this->success('', $config);
    }

    /**
     * 获取登陆页配置
     * @return \think\response\Json
     */
    public function getLoginConfig()
    {
        $login = $this->model->getValueByKey('login');
        $site = $this->model->getValueByKey('site');
        $login['site_name'] = $site['name'] ?? '';
        $login['icp'] = $site['icp'] ?? '';
        $login['copyright'] = $site['copyright'] ?? '';
        $login['is_get'] = 1;
        return $this->success('', $login);
    }

    // 获取系统配置
    public function getAllConfig()
    {
        $login = $this->model->getValueByKey('login');
        $site = $this->model->getValueByKey('site');

        // 获取hooks数据
        $hooks = ['customer_menu_hook', 'header_user_left_hook', 'header_user_right_hook'];
        $hookData = [];

        // 清理dkSys参数，移除潜在危险内容
        $clean_dkSys = $this->cleanDkSys(input('dkSys', []));

        foreach ($hooks as $hook) {
            $event = event($hook, $clean_dkSys);
            $stringData = '';
            $arrayData = [];

            foreach ($event as $hookResult) {
                if (is_string($hookResult)) {
                    // 如果是字符串，拼接HTML
                    $stringData .= $this->sanitizeHookOutput($hookResult);
                } elseif (is_array($hookResult)) {
                    // 如果是数组，合并数组
                    $arrayData = array_merge($arrayData, $hookResult);
                }
            }

            // 优先使用字符串数据，如果没有字符串数据则使用数组数据
            if (!empty($stringData)) {
                $hookData[$hook] = $stringData;
            } elseif (!empty($arrayData)) {
                $hookData[$hook] = $arrayData;
            } else {
                $hookData[$hook] = '';
            }
        }

        return $this->success('ok', [
            'login' => $login,
            'site'  => $site,
            'hooks' => $hookData,
        ]);
    }

    /**
     * 清理dkSys参数
     * @param array $dkSys
     * @return array
     */
    private function cleanDkSys($dkSys = [])
    {
        if (!is_array($dkSys)) {
            return [];
        }

        $clean = [];
        foreach ($dkSys as $key => $value) {
            // 只保留允许的键
            if (in_array($key, ['plaid', 'appid', 'uid'])) {
                $clean[$key] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
            }
        }

        return $clean;
    }

    /**
     * 清理hook输出
     * @param string $output
     * @return string
     */
    private function sanitizeHookOutput($output)
    {
        if (!is_string($output)) {
            return '';
        }

        // 移除危险的脚本标签和iframe
        $output = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $output);
        $output = preg_replace('/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/mi', '', $output);

        // 移除危险属性和协议
        $output = preg_replace('/\bon\w+\s*=\s*["\'][^"\']*["\']/', '', $output);
        $output = preg_replace('/\bjavascript\s*:/i', '', $output);
        $output = preg_replace('/\bdata\s*:/i', '', $output);

        // 允许一些基本的HTML标签（根据需要调整）
        $allowedTags = '<a><span><div><p><img><i><b><strong><em><u><br><hr>';
        $output = strip_tags($output, $allowedTags);

        return $output;
    }

    protected function getOption($array)
    {
        $option = [];
        foreach ($array as $key => $value) {
            $option[] = ['label' => $value, 'value' => $value];
        }
        return $option;
    }
}
